<?php

namespace app\command;

use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\console\input\Argument;
use think\facade\Db;
use think\facade\Log;
use PhpOffice\PhpSpreadsheet\IOFactory;

class CustomerImport extends Command
{
    // 状态映射（保持不变）
    protected $statusMap = ['无效客户' => 1, '成交客户' => 2, '忠诚客户' => 3];
    protected $stageMap = ['流失' => 1, '确认需求' => 2, '成交' => 3];
    protected $typeMap = ['零售客户' => 1, '渠道客户' => 2, '高级渠道客户' => 3, '批发客户' => 4, '网站客户' => 5, '其他' => 99];
    protected $natureMap = ['企业客户' => 1, '个人客户' => 2, '其他' => 99];
    protected $sourceMap = [
        '社媒社群' => 1, '官网直客' => 2, '抓取' => 3, '平台网店' => 4,
        '网络推广' => 5, '电话销售' => 6, '渠道代理' => 7, '线下自寻' => 8, '其他' => 9
    ];

    protected function configure()
    {
        $this->setName('customer:import')
            ->addArgument('file', Argument::REQUIRED, 'Excel文件路径')
            ->setDescription('导入客户数据');
    }

    protected function execute(Input $input, Output $output)
    {
        // 解除脚本限制
        set_time_limit(0);
        ini_set('memory_limit', '-1');

        $filePath = $input->getArgument('file');
        $startTime = microtime(true);

        $output->writeln("开始处理文件: {$filePath}");
        Log::info("开始处理文件: {$filePath}".json_encode(['file_path' => $filePath], JSON_UNESCAPED_UNICODE));

        try {
            if (!file_exists($filePath)) {
                $output->writeln("<error>错误：文件不存在: {$filePath}</error>");
                Log::error("文件不存在".json_encode(['file_path' => $filePath], JSON_UNESCAPED_UNICODE));
                return;
            }

            $output->writeln("加载Excel文件...");
            Log::info("开始加载Excel文件");
            $spreadsheet = IOFactory::load($filePath);
            $sheet = $spreadsheet->getActiveSheet();
            $rows = $sheet->toArray();

            if (count($rows) <= 1) {
                $output->writeln("<error>错误：Excel文件中没有数据行</error>");
                Log::error("Excel文件中没有数据行");
                return;
            }

            $titles = $rows[0];
            $output->writeln("检测到数据列：");
            $output->writeln(implode(" | ", $titles));
            Log::info("检测到标题行".json_encode(['titles' => $titles], JSON_UNESCAPED_UNICODE));

            array_shift($rows);
            $total = count($rows);

            $output->writeln("共发现 {$total} 条记录");
            Log::info("发现 {$total} 条记录");

            $customerGroups = [];
            $emptyNameCount = 0;

            // === 详细记录处理：每行数据都记录行号 ===
            foreach ($rows as $index => $row) {
                $excelRowNum = $index + 2;

                if (empty($row[1])) {
                    $emptyNameCount++;
                    $logMsg = "Excel第 {$excelRowNum} 行客户名称为空，已跳过";
                    $output->writeln("<comment>{$logMsg}</comment>");
                    Log::warning($logMsg.json_encode([
                            'excel_row' => $excelRowNum,
                            'row_data' => $row
                        ], JSON_UNESCAPED_UNICODE));
                    continue;
                }

                $dataId = $row[0] ?? 0;
                $customerGroups[$dataId][] = [
                    'row' => $row,
                    'excel_row' => $excelRowNum
                ];
            }

            $groupCount = count($customerGroups);
            $validRowCount = $total - $emptyNameCount;

            $output->writeln("有效记录数：{$validRowCount}");
            $output->writeln("空客户名称记录：{$emptyNameCount}");
            $output->writeln("分组后共 {$groupCount} 个客户组");
            Log::info("客户分组完成".json_encode([
                    'total_rows' => $total,
                    'empty_name_rows' => $emptyNameCount,
                    'customer_groups' => $groupCount
                ], JSON_UNESCAPED_UNICODE));

            $success = 0;
            $fail = 0;
            $currentGroup = 1;

            foreach ($customerGroups as $dataId => $groupItems) {
                $groupSize = count($groupItems);
                $logPrefix = "[组 {$currentGroup}/{$groupCount}] data_id:{$dataId}";

                $output->writeln("{$logPrefix} 记录数:{$groupSize}");

                $excelRows = array_column($groupItems, 'excel_row');
                $excelRowsStr = implode(',', $excelRows);

                Log::info("{$logPrefix} 开始处理".json_encode([
                        'data_id' => $dataId,
                        'rows_count' => $groupSize,
                        'excel_rows' => $excelRowsStr,
                        'sample_row' => $groupItems[0]['row']
                    ], JSON_UNESCAPED_UNICODE));

                try {
                    $mergedData = $this->mergeCustomerRecords($groupItems);
                    $mergedDataForContact = $this->mergeCustomerContactRecords($groupItems);

                    $output->writeln("  > 合并结果: 客户名={$mergedData['cusname']}");
                    $output->writeln("  > 联系方式: 手机={$mergedData['phone']}, 邮箱={$mergedData['email']}");
                    Log::info("客户组合并结果".json_encode([
                            'data_id' => $dataId,
                            'excel_rows' => $excelRowsStr,
                            'cusname' => $mergedData['cusname'],
                            'merged_phone' => $mergedData['phone'],
                            'merged_email' => $mergedData['email']
                        ], JSON_UNESCAPED_UNICODE));

                    $result = $this->processCustomer($mergedData,$mergedDataForContact, $excelRowsStr, $output);

                    if ($result) {
                        $success++;
                        $output->writeln("  √ 处理成功");
                    } else {
                        $fail++;
                        $output->writeln("  x 处理失败");
                        Log::error("客户处理失败".json_encode([
                                'dataId' => $dataId,
                                'excel_rows' => $excelRowsStr,
                                'data' => $mergedData
                            ], JSON_UNESCAPED_UNICODE));
                    }
                } catch (\Exception $e) {
                    $fail++;
                    $errorMsg = "Excel行 {$excelRowsStr} 处理异常: " . $e->getMessage() .
                        " [位于文件: {$e->getFile()} 第{$e->getLine()}行]";
                    $output->writeln("  x {$errorMsg}");
                    Log::error($errorMsg.json_encode([
                            'exception_file' => $e->getFile(),
                            'exception_line' => $e->getLine(),
                            'exception' => $e->getTraceAsString(),
                            'rows' => $groupItems
                        ], JSON_UNESCAPED_UNICODE));
                }

                $currentGroup++;
            }

            $elapsed = round(microtime(true) - $startTime, 2);
            $avgTime = $elapsed > 0 ? round($elapsed / $groupCount, 3) : 0;

            $output->writeln("\n========== 导入完成 ==========");
            $output->writeln("共发现 {$total} 条记录");
            $output->writeln("处理组数: {$groupCount}");
            $output->writeln("总耗时: {$elapsed} 秒");
            $output->writeln("成功: {$success} | 失败: {$fail}");
            $output->writeln("平均每组耗时: {$avgTime} 秒");

            Log::info("导入完成".json_encode([
                    'total_rows' => $total,
                    'customer_groups' => $groupCount,
                    'success' => $success,
                    'fail' => $fail,
                    'elapsed_time' => $elapsed,
                    'avg_time_per_group' => $avgTime
                ], JSON_UNESCAPED_UNICODE));

        } catch (\Exception $e) {
            $errorMsg = "导入失败: " . $e->getMessage() .
                " [位于文件: {$e->getFile()} 第{$e->getLine()}行]";
            $output->writeln("<error>{$errorMsg}</error>");
            Log::error($errorMsg.json_encode([
                    'file' => $filePath,
                    'exception_file' => $e->getFile(),
                    'exception_line' => $e->getLine(),
                    'trace' => $e->getTraceAsString()
                ], JSON_UNESCAPED_UNICODE));
        }
    }

    private function parseRow(array $row, int $excelRow): array
    {
        $row = array_map(function($value) {
            if (is_array($value)) {
                return implode(', ', $value);
            }
            return $value;
        }, $row);
        $parsedData = [
            'excel_row'     => $excelRow,
            'data_id'       => $row[0],
            'cusname'       => $row[1],
            'contact_type'  => $row[2] ?? '',
            'contact_value' => $row[3] ?? '',
            'email_column'  => $row[4] ?? '',
            'phone_column'  => $row[5] ?? '',
            'province'      => $row[6] ?? '',
            'city_col'      => $row[7] ?? '',
            'district'      => $row[8] ?? '',
            'address'       => $row[9] ?? '',
            'status'        => $this->mapStatus($row[10] ?? '', $excelRow),
            'stage'         => $this->mapStage($row[11] ?? '', $excelRow),
            'loss'          => $row[12] ?? '',
            'owner'          => $row[13] ?? '',
            'partner_str'   => $row[14] ?? '',
            'custype'       => $this->mapType($row[15] ?? '', $excelRow),
            'cusnature'     => $this->mapNature($row[16] ?? '', $excelRow),
            'source'        => $this->mapSource($row[17] ?? '', $excelRow),
            'country'       => $row[18] ?? '',
            'remark'        => $row[19] ?? '',
            'creator'       => $row[20] ?? '',
            'create_time'   => $this->parseDate($row[21] ?? '', $excelRow),
            'update_time'   => $this->parseDate($row[22] ?? '', $excelRow),
            'allocate_time' => $this->parseDate($row[23] ?? '', $excelRow),
            'phone'         => $this->extractPhone($row, $excelRow),
            'email'         => $this->extractEmail($row, $excelRow)
        ];

        Log::info("Excel行 {$excelRow} 解析结果".json_encode([
                'excel_row' => $excelRow,
                'parsed_data' => $parsedData
            ], JSON_UNESCAPED_UNICODE));

        return $parsedData;
    }

    private function mergeCustomerRecords(array $groupItems): array
    {
        $firstItem = $groupItems[0];
        $primaryRecord = $this->parseRow($firstItem['row'], $firstItem['excel_row']);
        if($primaryRecord['phone'] && $primaryRecord['email']){
            return $primaryRecord;
        }
        $contactInfo = [
            'phone' => $primaryRecord['phone'],
            'email' => $primaryRecord['email']
        ];
        Log::info("contactInfo  ".json_encode($contactInfo, JSON_UNESCAPED_UNICODE));
        $mergeLog = [];
        $excelRows = [];

        foreach ($groupItems as $item) {
            $excelRow = $item['excel_row'];
            $row = $item['row'];

            $excelRows[] = $excelRow;
            $record = $this->parseRow($row, $excelRow);
            Log::info("联系方式合并单行日志".json_encode($record, JSON_UNESCAPED_UNICODE));
            $foundPhone = false;
            $foundEmail = false;
            if (empty($contactInfo['phone']) && !empty($record['phone'])) {
                $contactInfo['phone'] = $record['phone'];
                $foundPhone = true;
            }
            if (empty($contactInfo['email']) && !empty($record['email'])) {

                $contactInfo['email'] = $record['email'];
                $foundEmail = true;
            }

            if ($foundPhone || $foundEmail) {
                $logEntry = "Excel行 {$excelRow}: ";
                if ($foundPhone) $logEntry .= "手机={$record['phone']} ";
                if ($foundEmail) $logEntry .= "邮箱={$record['email']}";
                $mergeLog[] = $logEntry;
            }
        }

        $primaryRecord['phone'] = $contactInfo['phone'];
        $primaryRecord['email'] = $contactInfo['email'];
        $primaryRecord['excel_rows'] = implode(',', $excelRows);

        Log::info("联系方式合并日志".json_encode([
                'data_id' => $primaryRecord['data_id'],
                'excel_rows' => $primaryRecord['excel_rows'],
                'cusname' => $primaryRecord['cusname'],
                'merge_log' => $mergeLog,
                'final_phone' => $contactInfo['phone'],
                'final_email' => $contactInfo['email']
            ], JSON_UNESCAPED_UNICODE));

        return $primaryRecord;
    }

    private function mergeCustomerContactRecords(array $groupItems): array
    {
        $excelRows = [];
        $contact = [
            'phone' => null,
            'email' => null,
            'telegram' => null,
            'whatsapp' => null,
            'wechat' => null,
        ];

        foreach ($groupItems as $item) {
            $excelRow = $item['excel_row'];
            $row = $item['row'];

            $excelRows[] = $excelRow;
            $record = $this->parseRow($row, $excelRow);
            Log::info("联系方式合并单行日志" . json_encode($record, JSON_UNESCAPED_UNICODE));

            switch ($record['contact_type']) {

                case 'Email':
                    if($contact['email']){
                        $contact['email'] .= ' '.$record['contact_value'];
                    }else{
                        $contact['email'] = $record['contact_value'];
                    }
                    break;
                case '微信':
                    if($contact['wechat']){
                        $contact['wechat'] .= ' '.$record['contact_value'];
                    }else{
                        $contact['wechat'] = $record['contact_value'];
                    }
                    break;
                case '手机':
                    if($contact['phone']){
                        $contact['phone'] .= ' '.$record['contact_value'];
                    }else{
                        $contact['phone'] = $record['contact_value'];
                    }
                    break;
                case 'WhatsApp':
                    if($contact['whatsapp']){
                        $contact['whatsapp'] .= ' '.$record['contact_value'];
                    }else{
                        $contact['whatsapp'] = $record['contact_value'];
                    }
                    break;
                case 'Telegram':
                    if($contact['telegram']){
                        $contact['telegram'] .= ' '.$record['contact_value'];
                    }else{
                        $contact['telegram'] = $record['contact_value'];
                    }
                    break;

            }

        }
        Log::info("联系方式合并" . json_encode($contact, JSON_UNESCAPED_UNICODE));
        return $contact;
    }

    private function extractEmail(array $row, int $excelRow): string
    {

        if (!empty($row[4]) && filter_var($row[4], FILTER_VALIDATE_EMAIL)) {
            Log::info("Excel行 {$excelRow} 邮箱提取成功: 客户Email列".json_encode([
                    'value' => $row[4]
                ], JSON_UNESCAPED_UNICODE));
            return $row[4];
        }

        $contactType = $row[2] ?? '';

        if (stripos($contactType, '邮箱') !== false || stripos($contactType, 'Email') !== false) {
            $contactValue = $row[3] ?? '';

            if (!empty($contactValue) && filter_var($contactValue, FILTER_VALIDATE_EMAIL)) {
                Log::info("Excel行 {$excelRow} 邮箱提取成功: 联系方式列".json_encode([
                        'contact_type' => $contactType,
                        'value' => $contactValue
                    ], JSON_UNESCAPED_UNICODE));
                return $contactValue;
            }
        }

        $logMsg = "Excel行 {$excelRow} 邮箱提取失败";
        Log::info($logMsg.json_encode([
                'contact_type' => $row[2] ?? '',
                'contact_value' => $row[3] ?? '',
                'email_column' => $row[4] ?? '',
                'possible_reason' => '格式无效或空值'
            ], JSON_UNESCAPED_UNICODE));

        return '';
    }

    private function extractPhone(array $row, int $excelRow): string
    {
        if (!empty($row[5])) {
            $cleanPhone = $this->cleanPhone($row[5]);
            Log::info("Excel行 {$excelRow} 手机号提取成功: 客户电话列".json_encode([
                    'original' => $row[5],
                    'clean_phone' => $cleanPhone
                ], JSON_UNESCAPED_UNICODE));
            return $cleanPhone;
        }

        $contactType = $row[2] ?? '';
        if (stripos($contactType, '手机') !== false || stripos($contactType, '电话') !== false) {
            $contactValue = $row[3] ?? '';
            $cleanPhone = $this->cleanPhone($contactValue);
            if (!empty($cleanPhone)) {
                Log::info("Excel行 {$excelRow} 手机号提取成功: 联系方式列".json_encode([
                        'contact_type' => $contactType,
                        'original' => $contactValue,
                        'clean_phone' => $cleanPhone
                    ], JSON_UNESCAPED_UNICODE));
                return $cleanPhone;
            }
        }

        $logMsg = "Excel行 {$excelRow} 手机号提取失败";
        Log::info($logMsg.json_encode([
                'contact_type' => $row[2] ?? '',
                'contact_value' => $row[3] ?? '',
                'phone_column' => $row[5] ?? '',
                'possible_reason' => '无效格式或空值'
            ], JSON_UNESCAPED_UNICODE));

        return '';
    }

    private function cleanPhone($phone): string
    {
        if (empty($phone)) return '';
        return $phone;
    }

    private function mapStatus($value, int $excelRow): int
    {
        $mapped = $this->statusMap[$value] ?? 0;
        Log::info("Excel行 {$excelRow} 状态映射: {$value} => {$mapped}");
        return $mapped;
    }

    private function mapStage($value, int $excelRow): int
    {
        $mapped = $this->stageMap[$value] ?? 0;
        Log::info("Excel行 {$excelRow} 阶段映射: {$value} => {$mapped}");
        return $mapped;
    }

    private function mapType($value, int $excelRow): int
    {
        $mapped = $this->typeMap[$value] ?? 99;
        Log::info("Excel行 {$excelRow} 类型映射: {$value} => {$mapped}");
        return $mapped;
    }

    private function mapNature($value, int $excelRow): int
    {
        $mapped = $this->natureMap[$value] ?? 99;
        Log::info("Excel行 {$excelRow} 性质映射: {$value} => {$mapped}");
        return $mapped;
    }

    private function mapSource($value, int $excelRow): int
    {
        $mapped = $this->sourceMap[$value] ?? 9;
        Log::info("Excel行 {$excelRow} 来源映射: {$value} => {$mapped}");
        return $mapped;
    }

    private function parseDate($date, int $excelRow)
    {
        if (empty($date)) {
            Log::info("Excel行 {$excelRow} 日期解析: 空值");
            return null;
        }

        try {
            if (is_numeric($date)) {
                $timestamp = intval(($date - 25569) * 86400);
                $result = date('Y-m-d H:i:s', $timestamp);
                Log::info("Excel行 {$excelRow} 日期解析(Excel格式): {$date} => {$result}");
                return $result;
            }

            $result = date('Y-m-d H:i:s', strtotime($date));
            Log::info("Excel行 {$excelRow} 日期解析(字符串): {$date} => {$result}");
            return $result;
        } catch (\Exception $e) {
            $logMsg = "Excel行 {$excelRow} 日期解析失败: {$date}";
            Log::warning($logMsg.json_encode(['error' => $e->getMessage()], JSON_UNESCAPED_UNICODE));
            return null;
        }
    }

    private function processCustomer(array $data,$mergedDataForContact, string $excelRows, Output $output): bool
    {
        $cityParts = [
            $data['province'],
            $data['city_col'],
            $data['district']
        ];
        $data['city'] = trim(implode(' ', $cityParts));

        Log::info("Excel行 {$excelRows} 省市区合并".json_encode([
                'province' => $data['province'],
                'city_col' => $data['city_col'],
                'district' => $data['district'],
                'result' => $data['city']
            ], JSON_UNESCAPED_UNICODE));

        $dbData = [
            'cusname'      => $data['cusname'],
            'phone'        => $data['phone'],
            'email'        => $data['email'],
            'address'      => $data['address'],
            'city'         => $data['city'],
            'status'       => $data['status'],
            'stage'        => $data['stage'],
            'loss'         => $data['loss'],
            'partner'      => $data['partner_str'],
            'custype'      => $data['custype'],
            'cusnature'    => $data['cusnature'],
            'source'       => $data['source'],
            'remark'       => $data['remark'],
            'create_time'  => $data['create_time'],
            'update_time'  => $data['update_time'] ?: date('Y-m-d H:i:s'),
            'allocate_time'=> $data['allocate_time'],
        ];

        // ====== 优化点1：owner字段处理（只取第一个值）======
        $ownerName = !empty($data['owner']) ? trim(explode(',', $data['owner'])[0]) : '';
        $ownerId = $this->getOperatorId($ownerName, $excelRows);
        $dbData['owner'] = $ownerId;

        // ====== 优化点2：creator字段处理（只取第一个值）======
        $creatorName = !empty($data['creator']) ? trim(explode(',', $data['creator'])[0]) : '';
        $creatorId = $this->getOperatorId($creatorName, $excelRows);
        $dbData['creator'] = $creatorId;

        // ====== 优化点3：partner字段处理（多个值）======
        $partnerNames = !empty($data['partner_str']) ? explode(',', $data['partner_str']) : [];
        $partnerIds = [];
        foreach ($partnerNames as $name) {
            $cleanName = trim($name);
            if (!empty($cleanName)) {
                $partnerId = $this->getOperatorId($cleanName, $excelRows);
                if ($partnerId > 0) {
                    $partnerIds[] = $partnerId;
                }
            }
        }
        $dbData['partner'] = implode(',', $partnerIds);

        if (!empty($data['country'])) {
            $countryId = Db::name('region_country')
                ->where('cname', $data['country'])
                ->value('id');

            $dbData['country_id'] = $countryId ?: 0;

            Log::info("Excel行 {$excelRows} 国家查询".json_encode([
                    'country_name' => $data['country'],
                    'country_id' => $countryId
                ], JSON_UNESCAPED_UNICODE));
        } else {
            $dbData['country_id'] = 0;
            Log::info("Excel行 {$excelRows} 国家为空");
        }

        $criteria = [['cusname', '=', $data['cusname']]];
        if ($dbData['phone']) $criteria[] = ['phone', '=', $dbData['phone']];
        if ($dbData['email']) $criteria[] = ['email', '=', $dbData['email']];

        Log::info("Excel行 {$excelRows} 客户匹配查询条件".json_encode([
                'criteria' => $criteria
            ], JSON_UNESCAPED_UNICODE));

        $output->writeln("  > 准备写入数据库的数据：");
        $output->writeln("    - Excel行号: {$excelRows}");
        $output->writeln("    - 客户名称: {$dbData['cusname']}");
        $output->writeln("    - 手机号: {$dbData['phone']}");
        $output->writeln("    - 邮箱: {$dbData['email']}");
        $output->writeln("    - 完整地址: {$dbData['address']} | {$dbData['city']}");
        $output->writeln("    - 客户状态: {$data['status']} => {$dbData['status']}");
        $output->writeln("    - 客户阶段: {$data['stage']} => {$dbData['stage']}");
        $output->writeln("    - 客户类型: {$data['custype']} => {$dbData['custype']}");
        $output->writeln("    - 客户性质: {$data['cusnature']} => {$dbData['cusnature']}");
        $output->writeln("    - 来源: {$data['source']} => {$dbData['source']}");
        $output->writeln("    - 负责人: {$data['owner']} => ID: {$ownerId} (取第一个值: {$ownerName})");
        $output->writeln("    - 创建人: {$data['creator']} => ID: {$creatorId} (取第一个值: {$creatorName})");
        $output->writeln("    - 合作伙伴: {$data['partner_str']} => ID列表: {$dbData['partner']}");
        $output->writeln("    - 创建时间: {$dbData['create_time']}");
        $output->writeln("    - 更新时间: {$dbData['update_time']}");
        $output->writeln("    - 分配时间: {$dbData['allocate_time']}");
        $output->writeln("    - 国家ID: {$dbData['country_id']}");
        $output->writeln("    - 备注: {$dbData['remark']}");
        $output->writeln("    - 流失原因: {$dbData['loss']}");

        $exists = Db::name('customer')
            ->whereOr($criteria)
            ->find();

        try {
            if ($exists) {
                Db::name('customer')
                    ->where('id', $exists['id'])
                    ->update($dbData);

                Log::info("Excel行 {$excelRows} 更新客户记录".json_encode([
                        'customer_id' => $exists['id'],
                        'changes' => $dbData
                    ], JSON_UNESCAPED_UNICODE));
                $insertId = $exists['id'];
            } else {
                $insertId = Db::name('customer')->insertGetId($dbData);

                Log::info("Excel行 {$excelRows} 创建新客户记录".json_encode([
                        'customer_id' => $insertId,
                        'data' => $dbData
                    ], JSON_UNESCAPED_UNICODE));

            }

            $exist_con = Db::name('customer_contact')
                ->where('cusid',$insertId)
                ->order('create_time asc')
                ->find();
            if($exist_con){
                Db::name('customer_contact')
                    ->where('id', $exist_con['id'])
                    ->update($mergedDataForContact);
            }else{
                $mergedDataForContact['cusid'] = $insertId;
                $mergedDataForContact['create_time'] = date('Y-m-d H:i:s');
                $mergedDataForContact['creator'] = 0;
                Db::name('customer_contact')->insert($mergedDataForContact);
            }
            return true;
        } catch (\Exception $e) {
            $errorMsg = "Excel行 {$excelRows} 数据库操作失败: " . $e->getMessage() .
                " [位于文件: {$e->getFile()} 第{$e->getLine()}行]";
            Log::error($errorMsg.json_encode([
                    'excel_rows' => $excelRows,
                    'data' => $dbData,
                    'exists_id' => $exists['id'] ?? null,
                    'exception_file' => $e->getFile(),
                    'exception_line' => $e->getLine(),
                    'error' => $e->getTraceAsString()
                ], JSON_UNESCAPED_UNICODE));
            return false;
        }
    }

    private function getOperatorId($name, string $excelRows): int
    {
        if (empty($name)) {
            Log::info("Excel行 {$excelRows} 负责人处理: 名称为空");
            return 0;
        }

        $names = explode(',', $name);
        $firstName = trim($names[0]);

        $operatorId = Db::name('operator')
            ->where('cname', $firstName)
            ->value('id');

        if ($operatorId) {
            Log::info("Excel行 {$excelRows} 负责人查询成功: {$firstName} => {$operatorId}");
            return $operatorId;
        }

        $logMsg = "Excel行 {$excelRows} 负责人未找到: {$firstName}";
        Log::warning($logMsg);
        return 0;
    }
}